6.04. Руководство программиста по ГОСТ 19.504-79
Руководство программиста
1. Введение: стандарт и его роль
1.1 Общая характеристика ГОСТ 19.504-79
- Наименование документа: Руководство программиста
- Статус: Государственный стандарт СССР, действует по сей день в РФ как межгосударственный стандарт (соответствует СТ СЭВ 2095-80).
- Дата введения: 1 января 1980 г.
- Утверждён: Постановлением Госстандарта СССР от 12.01.1979 № 74.
- Область применения:
- Разработка и сопровождение программного обеспечения (ПО) в рамках Единой системы программной документации (ЕСПД).
- Обязателен к применению в организациях, работающих по ГОСТ 19.100–19.701 (ЕСПД), особенно в госсекторе, ОПК, энергетике, транспорте и других регулируемых отраслях.
💡 Примечание: Стандарт не отменён и часто используется в контексте требований к документации по ГОСТ Р ИСО/МЭК 12207 и 15288. В современной практике его требования адаптируются под agile, но базовая структура остаётся актуальной при составлении внутренней технической документации.
1.2 Назначение Руководства программиста
Руководство программиста — документ, предназначенный для разработчиков, включающий техническую информацию, необходимую для:
- интеграции программы в состав комплекса ПО;
- сопровождения и модификации;
- отладки и тестирования;
- обеспечения сопряжения с другими программами и системами.
Он не дублирует Руководство оператора (ГОСТ 19.505) и не заменяет Техническое задание (ГОСТ 19.201). Это — документ инженерного уровня, ориентированный на реализацию, а не на эксплуатацию.
1.3 Общая структура документа по ГОСТ
| Раздел | Обязательность | Краткое содержание |
|---|---|---|
| Титульный лист / реквизиты | Да | Назначение документа, наименование ПО, номер версии, дата, ответственные |
| Аннотация (информационная часть) | Да | Краткая характеристика, назначение, применимость |
| Содержание | Да | Оглавление с нумерацией разделов |
| 1. Назначение и условия применения программ | Обязательный | Цель, функции, требования к среде выполнения |
| 2. Характеристика программы | Обязательный | Режимы работы, временные/ресурсные характеристики, надёжность |
| 3. Обращение к программе | Обязательный | Способы вызова, интерфейсы, передача управления и параметров |
| 4. Входные и выходные данные | Обязательный | Форматы, структуры, кодировки, примеры |
| 5. Сообщения | Обязательный | Типы сообщений, тексты, действия при их возникновении |
| Приложения | Опционально | Доп. схемы, примеры кода, таблицы, протоколы |
📌 Важно: Структура оформляется в соответствии с ГОСТ 19.105-78 — требования к оформлению программных документов (шрифты, поля, нумерация, ссылки и т.п.).
2. Пошаговое руководство по составлению Руководства программиста
Ниже — детализированный порядок составления документа. Каждый шаг включает не только что писать, но и как, с акцентом на техническую точность и воспроизводимость.
Шаг 1. Подготовительный этап
- Определите полный состав программных модулей, к которым будет относиться документ:
- Это может быть один модуль, подсистема или целая система (если она атомарна по функционалу).
- Убедитесь, что у вас есть актуальные:
- Архитектурная схема (в том числе API-контракты);
- Техническое задание (ГОСТ 19.201);
- Документация по использованным технологиям (SDK, runtime, библиотеки);
- Спецификация данных (ERD / JSON Schema / XSD).
- Назначьте ответственных:
- Разработчик — поставляет технические данные;
- Архитектор — утверждает интерфейсы и режимы;
- Техписатель — формирует и редактирует документ.
Шаг 2. Раздел «Назначение и условия применения программ»
Что включать:
-
Назначение:
«Программа
auth-serviceпредназначена для централизованной аутентификации и авторизации пользователей в распределённой системеX-Core. Реализует протоколы OAuth2.0 и OpenID Connect 1.0.» -
Функции: перечислить только программные функции, реализованные внутри модуля (не «взаимодействует с БД», а «осуществляет JWT-валидацию токенов», «реализует эндпоинты
/token,/userinfo,/revoke»). -
Условия применения (строго по категориям):
- Аппаратные требования:
- Минимальный объём RAM: 512 МБ
- Процессор: x86-64, 2 ядра
- Наличие TPM-2.0 (если требуется)
- Программные требования:
- ОС: Linux (Ubuntu 20.04+, AlmaLinux 8+)
- Среда: OpenJDK 17+, Node.js 18.x
- Зависимости: PostgreSQL 14+, Redis 6.2+, Vault 1.12+
- Сетевые требования:
- Доступ к порту 5432 (PostgreSQL), 6379 (Redis), 8200 (Vault)
- Возможность TLS-терминации на уровне ingress
- Аппаратные требования:
✅ Рекомендация: оформлять в виде таблиц.
❌ Ошибка: смешивать требования к системе и требования к разработке (например, «требуется опыт в Spring Security» — это НЕ условие применения, а требование к персоналу).
Пример оформления:
### 1. Назначение и условия применения программ
#### 1.1 Назначение
Модуль `calc-engine` реализует ядро расчёта финансовых показателей (IRR, NPV, DPP) для инвестиционных проектов в системе `X-Core`. Предоставляет REST API для клиентских сервисов.
#### 1.2 Функции
- Приём JSON-описания денежного потока;
- Расчёт IRR методом Ньютона–Рафсона (с итерационным уточнением);
- Валидация входных параметров (чек-лист: не пустой поток, не более 100 периодов, ставка в [0;1]);
- Логирование ошибок расчёта (коды 4xx/5xx).
#### 1.3 Условия применения
| Категория | Требование |
|-----------|------------|
| Аппаратное обеспечение | RAM ≥ 1 ГБ, CPU ≥ 2 vCPU |
| Операционная система | Linux (ядро ≥ 5.4) |
| Среда выполнения | Python 3.10+, `numpy==1.24.3`, `scipy==1.10.1` |
| Сетевые возможности | Доступ к `redis.internal:6379`, `logger.service:9000/udp` |
| Прочие ограничения | Не поддерживает Windows; требует `libgomp1` в системе |
Шаг 3. Раздел «Характеристика программы»
Это — «паспорт» поведения программы под нагрузкой и в штатных/нештатных режимах.
Обязательные подразделы (по смыслу ГОСТ):
-
Режим работы
- Пакетный / интерактивный / фоновый / реального времени
- Поддержка многопоточности, кластеризации, горизонтального масштабирования
- Ограничения на параллельные запросы (например,
max_concurrent_calculations = 50)
-
Временные характеристики
- Среднее/максимальное время выполнения операции (в ms)
- Зависимость от объёма входных данных
- Пример: «Обработка потока из 10 периодов: ≤ 15 мс (P95); из 100 периодов: ≤ 210 мс (P95)»
-
Средства контроля и самовосстановления
- Логирование: уровни, категории, формат (JSON, RFC5424)
- Метрики: экспортируемые через Prometheus (
calc_duration_seconds,calc_error_total) - Механизмы graceful degradation:
- fallback на упрощённый алгоритм при timeout > 500 мс
- circuit breaker после 5 ошибок подряд
- Health-check: эндпоинт
/healthz, возвращает{ "status": "ok", "deps": { "redis": true } }
✅ Рекомендация: приводить измеренные данные (benchmark-результаты), а не оценочные.
❌ Ошибка: использовать расплывчатые формулировки вроде «высокая производительность» без метрик.
Пример:
### 2. Характеристика программы
#### 2.1 Режим работы
- Интерактивный (запрос–ответ по HTTP/1.1 и HTTP/2);
- Поддержка до 200 одновременных соединений (ограничено `gunicorn --workers=4 --threads=50`);
- Stateless: все сессии хранятся в Redis.
#### 2.2 Временные характеристики (на стенде: 2 vCPU, 4 ГБ RAM, SSD)
| Размер входа | Среднее время, мс | P95, мс | P99, мс |
|--------------|-------------------|---------|---------|
| 10 периодов | 8.2 | 14.1 | 19.7 |
| 50 периодов | 42.6 | 88.3 | 120.4 |
| 100 периодов | 163.9 | 211.5 | 302.8 |
> 📊 Замеры выполнены с помощью `k6` (1000 VUs, 30s ramp-up).
#### 2.3 Средства контроля и самовосстановления
- **Логирование**:
- Уровень `INFO` — старт/стоп запроса, `ERROR` — исключения, `DEBUG` — детали расчёта (опционально).
- Формат: JSON, поля: `ts`, `level`, `req_id`, `module`, `msg`, `duration_ms`.
- **Метрики (Prometheus)**:
promql
calc_duration_seconds{quantile="0.95"}
calc_error_total{type="input_validation", method="POST"}
- **Health-check**:
http
GET /healthz
→ 200 OK
{
"status": "ok",
"version": "2.3.1",
"deps": {
"redis": true,
"vault": true
}
}
- **Self-healing**:
При недоступности Redis > 3 с — переключение на in-memory LRU-кэш (ёмкость 1000 записей), с логированием предупреждения `WARN cache.fallback redis_unavailable`.
Шаг 4. Раздел «Обращение к программе»
Этот раздел — интерфейсная спецификация. Должен позволить другому разработчику интегрировать модуль без доступа к исходному коду.
Что включать:
-
Способы вызова:
- REST API (методы, пути, заголовки)
- CLI (команды, флаги)
- Библиотечный интерфейс (публичные классы/функции)
- Сообщения (AMQP, Kafka, gRPC)
-
Передача управления и параметров:
- Как передаётся контекст (например,
X-Request-ID, JWT вAuthorization: Bearer …) - Формат тела запроса/ответа
- Правила маршалинга/демаршалинга
- Поведение при ошибках (статус-коды, структура
error)
- Как передаётся контекст (например,
✅ Рекомендация: использовать OpenAPI/Swagger-подобные фрагменты.
❌ Ошибка: описывать внутреннюю логику вместо контракта («функция сначала проверяет…» — не надо!).
Пример:
### 3. Обращение к программе
#### 3.1 REST API (`/api/v1/calc`)
| Метод | Путь | Описание |
|-------|------|----------|
| POST | `/irr` | Расчёт внутренней нормы доходности |
##### Запрос
http
POST /api/v1/calc/irr HTTP/1.1
Host: calc-engine.x-core.internal
Content-Type: application/json
X-Request-ID: a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8
Authorization: Bearer <JWT>
{
"cashflow": [
{"period": 0, "amount": -1000000},
{"period": 1, "amount": 300000},
{"period": 2, "amount": 400000},
{"period": 3, "amount": 500000}
],
"guess": 0.1
}
- `cashflow`: обязательный массив объектов:
- `period` (int ≥ 0, уникальный)
- `amount` (float, может быть отрицательным)
- `guess`: необязательный (float ∈ [0; 1]), стартовое приближение.
##### Ответ (успех, 200 OK)
json
{
"irr": 0.1278,
"iterations": 7,
"converged": true
}
##### Ответ (ошибка валидации, 400 Bad Request)
json
{
"error": "INVALID_INPUT",
"detail": "cashflow[1].period must be `> cashflow[0].period"
}
##### Коды ответов
| Код | Причина |
|-----|---------|
| 200 | Успешный расчёт |
| 400 | Ошибка валидации входных данных |
| 401 | Отсутствует/некорректный JWT |
| 429 | Превышен лимит запросов (100/сек/IP) |
| 500 | Внутренняя ошибка сервера (см. логи по `X-Request-ID`) |
| 503 | Сервис недоступен (Redis down, fallback active) |
Шаг 5. Раздел «Входные и выходные данные»
🔍 Смысл раздела (по ГОСТ 19.504-79, п. 2.4):
«Описание организации используемой входной и выходной информации и, при необходимости, её кодирования».
Этот раздел — не описание бизнес-логики, а техническая спецификация форматов данных. Критически важен для сопряжения, тестирования, генерации моков и документирования API-контрактов.
Что включать (по смыслу и практике ЕСПД):
| Элемент | Требования |
|---|---|
| Источники входных данных | Откуда поступают данные: API, файл, stdin, шина сообщений, БД-запрос, CLI-аргументы и т.п. |
| Структура входных данных | Структуры (JSON Schema, XSD, protobuf), поля, типы, ограничения (длина, диапазон, regexp), обязательность |
| Кодировки | UTF-8, CP1251, Base64, Hex — указывать явно, если не по умолчанию |
| Форматы файлов (если применимо) | CSV (разделитель, кавычки, escape), XML (DTD), JSON (RFC 8259), binary (endianness) |
| Выходные данные | Аналогично — структура, типы, кодировки, форматы |
| Изменения состояния | Какие ресурсы изменяются: запись в БД, кэш, файл, отправка события — с указанием ключей/идентификаторов |
✅ Рекомендация: прикладывать валидные примеры и невалидные (для пояснения ограничений).
❌ Типичная ошибка: описывать бизнес-смысл полей («amount— объём инвестиций»), тогда как нужно: «amount: float64, диапазон [-1e12; 1e12], 2 знака после запятой, обязательное».
Пример оформления:
### 4. Входные и выходные данные
#### 4.1 Источники входных данных
- HTTP-запрос (POST) к эндпоинту `/api/v1/calc/irr` (см. раздел 3);
- Входные данные передаются в теле запроса в формате JSON (RFC 8259);
- Кодировка: UTF-8 без BOM.
#### 4.2 Структура входных данных (JSON Schema Draft-07)
json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"required": ["cashflow"],
"properties": {
"cashflow": {
"type": "array",
"minItems": 1,
"maxItems": 100,
"items": {
"type": "object",
"required": ["period", "amount"],
"properties": {
"period": {
"type": "integer",
"minimum": 0,
"maximum": 1000
},
"amount": {
"type": "number",
"minimum": -1e12,
"maximum": 1e12,
"multipleOf": 0.01
}
},
"additionalProperties": false
}
},
"guess": {
"type": "number",
"minimum": 0.0,
"maximum": 1.0
}
},
"additionalProperties": false
}
#### 4.3 Примеры
##### Валидный запрос:
json
{
"cashflow": [
{"period": 0, "amount": -500000.00},
{"period": 1, "amount": 200000.00},
{"period": 2, "amount": 350000.00}
],
"guess": 0.15
}
##### Невалидный запрос (ошибка: неуникальный period):
json
{
"cashflow": [
{"period": 0, "amount": -100000},
{"period": 1, "amount": 50000},
{"period": 1, "amount": 60000} ← дубликат
]
}
→ Возвращается код 400 с ошибкой "DUPLICATE_PERIOD".
#### 4.4 Выходные данные
| Поле | Тип | Описание | Ограничения |
|------|-----|-----------|--------------|
| `irr` | number | Рассчитанное значение IRR | ∈ [–1; 1], 4 знака после запятой |
| `iterations` | integer | Число итераций метода Ньютона | ≥ 1, ≤ 1000 |
| `converged` | boolean | Сходимость достигнута | `true`/`false` |
| `warning` | string | (опционально) предупреждение | max 256 символов, UTF-8 |
> ⚠ Примечание: при `converged: false` поле `irr` содержит последнее приближение (не гарантируется корректность).
#### 4.5 Изменения состояния
- Логирование операции в `calc_log` (таблица в PostgreSQL):
- `req_id UUID NOT NULL`
- `user_id TEXT` (из JWT.claims.sub)
- `duration_ns BIGINT`
- `status TEXT` (`ok`, `input_error`, `timeout`, `diverge`)
- При `status = 'diverge'` — инкремент счётчика `diverge_counter` в Redis (`INCR calc:diverge:2025-11`).
Шаг 6. Раздел «Сообщения»
🔍 Смысл раздела (п. 2.5 ГОСТ):
«Тексты сообщений, выдаваемых программисту или оператору в ходе выполнения программы, описание их содержания и действий, которые необходимо предпринять по этим сообщениям».
⚠ Важно:
- «программисту или оператору» означает — любые диагностические сообщения, включая логи, HTTP-ошибки, CLI-вывод, алерты.
- Нужно разделять:
- Информационные (
INFO,DEBUG) - Предупреждения (
WARN) - Ошибки (
ERROR,FATAL)
- Информационные (
Для каждой категории — указать:
- Код/идентификатор (рекомендуется)
- Текст (точный, включая параметры в шаблоне)
- Условие возникновения
- Рекомендуемое действие
Пример оформления:
### 5. Сообщения
| Код | Уровень | Текст | Условие | Действие |
|-----|---------|-------|---------|----------|
| `CALC-001` | INFO | `Request {req_id} started. user={user_id}, cashflow_len={len}` | Начало обработки запроса | — |
| `CALC-002` | DEBUG | `Newton iteration {i}: x={x:.6f}, f(x)={fx:.3e}` | Включён `log_level=DEBUG` | Только для отладки; не в проде |
| `CALC-003` | WARN | `Fallback to in-memory cache: Redis unavailable (err={err})` | Таймаут подключения к Redis > 3 с | Проверить сетевую доступность Redis; кэш ограничен — возможна деградация |
| `CALC-004` | ERROR | `Input validation failed: {detail}` | Нарушение условий JSON Schema | Исправить клиентский запрос; проверить `X-Request-ID` в логах |
| `CALC-005` | ERROR | `Divergence after {n} iterations. guess={g}, last_irr={irr}` | Метод не сошёлся за 1000 итераций | Увеличить `guess` ближе к ожидаемому значению; или использовать `npv=0` для подбора вручную |
| `CALC-006` | FATAL | `Critical: Vault token expired. Cannot fetch decryption key.` | Vault возвращает 403 на `/transit/decrypt` | Перезапустить sidecar `vault-agent`; проверить lease duration |
> 📌 Все сообщения экспортируются в JSON-лог с полем `"msg_code": "CALC-004"`.
> 📌 Коды используют префикс `CALC-` + трёхзначный номер → легко фильтровать в SIEM.
4. Пример вымышленной системы: X-Core — Финансовый калькулятор
Ниже — фрагменты Руководства программиста для модуля calc-engine, оформленные строго по ГОСТ 19.504-79, без «воды», с фокусом на техническую реализуемость.
💡 Обратите внимание: в реальной практике такой документ может занимать 15–30 страниц. Приведены ключевые разделы — то, что реально используют при интеграции.
📄 Руководство программиста
Модуль: calc-engine (версия 2.3.1)
Система: X-Core
Дата: 11.11.2025
Разработчик: Тагиров Т.В.
Утверждено: Архитектурный комитет, протокол № 47 от 05.11.2025
1. Назначение и условия применения программ
1.1 Назначение
Программа calc-engine реализует численные методы расчёта финансовых показателей (IRR, NPV) для инвестиционных проектов. Предоставляет stateless REST API для сервисов user-portal и reporting.
1.2 Условия применения
| Категория | Требование |
|---|---|
| ОЗУ | ≥ 1 ГБ (реком.: 2 ГБ) |
| CPU | 2 ядра x86-64 (частота ≥ 2.4 ГГц) |
| ОС | Linux (ядра ≥ 5.4); не поддерживает Windows/macOS |
| Среда | Python 3.10+, numpy==1.24.3, scipy==1.10.1, gunicorn==21.2.0 |
| Зависимости | PostgreSQL 14+ (calc_log), Redis 6.2+ (cache), Vault 1.12+ (keys) |
| Сеть | Доступ к redis:6379, vault:8200, pg:5432; outbound HTTPS для метрик |
2. Характеристика программы
2.1 Режим работы
- Интерактивный, запрос–ответ;
- Поддержка до 200 concurrent-соединений (
gunicorn --workers=4 --threads=50); - Horizontally scalable: stateless → можно деплоить N реплик.
2.2 Временные характеристики
| Размер потока | P50 (мс) | P95 (мс) | P99 (мс) |
|---|---|---|---|
| 10 периодов | 8.2 | 14.1 | 19.7 |
| 50 периодов | 42.6 | 88.3 | 120.4 |
| 100 периодов | 163.9 | 211.5 | 302.8 |
📊 Замеры:
k6(1000 VUs, 30s), сервер: 4 vCPU, 8 ГБ RAM, NVMe. Алгоритм: Ньютон–Рафсон с fallback на бисекцию.
2.3 Средства контроля
- Health-check:
GET /healthz→{ "status": "ok", "deps": { "redis": true } } - Метрики:
calc_duration_seconds,calc_error_total{code}(экспорт в Prometheus) - Логи: JSON,
ts,level,req_id,msg_code,duration_ms - Circuit breaker: после 5 ошибок
CALC-005подряд — возврат 503 на 30 с.
3. Обращение к программе
3.1 REST API (/api/v1/calc)
| Эндпоинт | Метод | Описание |
|---|---|---|
/irr | POST | Расчёт IRR |
/npv | POST | Расчёт NPV при заданной ставке |
Заголовки:
- Обязательно:
Content-Type: application/json,Authorization: Bearer <JWT> - Рекомендуется:
X-Request-ID(генерируется клиентом)
См. полную OpenAPI-спецификацию в docs/openapi/calc-engine.v2.yaml.
4. Входные и выходные данные — см. пример выше (раздел 4).
5. Сообщения — см. таблицу выше (раздел 5).
5. Чек-лист: Проверка Руководства программиста перед утверждением
Используйте этот список при ревью. Достаточно одного «Нет» — документ требует доработки.
| № | Критерий | Да / Нет | Комментарий |
|---|---|---|---|
| 1 | Есть аннотация (назначение, версия, ответственные)? | ||
| 2 | Есть содержание с правильной нумерацией? | ||
| 3 | Раздел 1: указаны точные требования к среде (не «современный ПК», а «RAM ≥ 1 ГБ»)? | ||
| 4 | Раздел 2: есть измеренные временные характеристики (не «быстро»)? | ||
| 5 | Раздел 3: есть полный контракт вызова (метод, заголовки, тело, коды ответа)? | ||
| 6 | Раздел 4: есть валидный пример входных/выходных данных? | ||
| 7 | Раздел 4: указаны ограничения на поля (диапазон, длина, формат)? | ||
| 8 | Раздел 5: каждое сообщение имеет код, точный текст, условие, действие? | ||
| 9 | Все примеры воспроизводимы (можно скопировать в Postman и получить ответ)? | ||
| 10 | Нет упоминаний внутренней реализации («функция сначала проверяет…»)? | ||
| 11 | Нет расплывчатых формулировок («высокая надёжность», «гибкая настройка»)? | ||
| 12 | Документ соответствует ГОСТ 19.105-78 по оформлению (шрифты, поля, заголовки)? |
📌 Рекомендуется: прогонять документ через peer review с участием как минимум одного разработчика и одного техписателя.